﻿using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using TXTD.Admin.Data.Entitys;
using TXTD.Admin.Data.Entitys.System;
using TXTD.Admin.Framework.Reflection;
using TXTD.Admin.Interface;
using TXTD.Admin.Model.Paging;

namespace TXTD.Admin.Service
{
    public class BaseService<T> : IBaseService<T> where T : BaseEntity
    {
        public readonly DbContext db;
        public readonly HttpContext _HttpContext;
        /// <summary>
        /// 当前登录用户
        /// </summary>
        public readonly SysUser? LoginUser = null;
        public BaseService(DbContext dbContext, IHttpContextAccessor httpContextAccessor)
        {
            db = dbContext;
            _HttpContext = httpContextAccessor.HttpContext;

            #region 获取登录用户
            if (_HttpContext != null)
            {
                var UserId = _HttpContext.User.Claims.FirstOrDefault(t => t.Type == "UserId");
                if (UserId != null)
                {
                    LoginUser = db.Set<SysUser>().FirstOrDefault(t => t.UserId == UserId.Value);
                }
            }
            #endregion
        }
        /// <summary>
        /// 获取所有数据
        /// </summary>
        /// <returns></returns>
        public DbSet<T> QueryAllData()
        {
            return db.Set<T>();
        }
        /// <summary>
        /// 获取分页数据列表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public PageResult<TargetT> QueryPageList<TargetT>(Expression<Func<T, bool>> where)
            where TargetT : class, new()
        {
            PageInfo pageInfo = new PageInfo();

            HttpRequest request = _HttpContext.Request;

            pageInfo.PageSize = int.Parse(request.Query["pageSize"]);
            pageInfo.PageIndex = int.Parse(request.Query["page"]);

            IQueryable<T> list = db.Set<T>();
            if (where != null)
                list = list.Where(where);

            pageInfo.TotalCount = list.Count();

            //分页
            list = list.Skip(pageInfo.SkipCount).Take(pageInfo.TakeCount);

            return new PageResult<TargetT>()
            {
                Page = pageInfo.PageIndex,
                PageCount = pageInfo.TotalPageCount,
                PageSize = pageInfo.PageSize,
                List = ReflectionModelUtil.CopyDataList<TargetT, T>(list.ToList())
            };
        }
        /// <summary>
        /// 根据id获取数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T GetModelById(string id)
        {
            return db.Set<T>().Find(id);
        }
        /// <summary>
        /// 插入一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public int InsertModel(T t)
        {
            if (LoginUser != null)
            {
                t.CreatedBy = LoginUser.UserId;
            }
            t.CreatedTime = DateTime.Now;
            _ = db.Set<T>().Add(t);
            return db.SaveChanges();
        }
        /// <summary>
        /// 修改一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public int UpdateModel(T t, string id)
        {
            T? data = db.Set<T>().Find(id);
            if (data != null)
            {
                ReflectionModelUtil.CopyData<T>(data, t);
                if (LoginUser != null)
                {
                    data.UpdatedBy = LoginUser.UserId;
                }
                data.UpdatedTime = DateTime.Now;
                return db.SaveChanges();
            }
            return 0;
        }
        /// <summary>
        /// 删除一条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public int RemoveModel(T t)
        {
            _ = db.Set<T>().Remove(t);
            return db.SaveChanges();
        }
        /// <summary>
        /// 删除一条数据 根据ID
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public int RemoveById(string id)
        {
            T? t = db.Set<T>().Find(id);
            if (t != null)
                return RemoveModel(t);
            return 0;
        }
    }
}